package tksMail

import (
	"encoding/base64"
	"fmt"
	"net/mail"
	"net/smtp"
	"strings"
)

type TksMailInfo struct {
	tomail string
	title  string
	body   string
}

type TksMailAuth struct {
	server string
	auth   smtp.Auth
	from   mail.Address
	in     chan *TksMailInfo
}

func CreateMailInfo(server string, mailacc string, mailpwd string, mailname string) *TksMailAuth {
	auth := new(TksMailAuth)
	auth.server = server
	auth.auth = smtp.PlainAuth(
		"",
		mailacc,
		mailpwd,
		server,
	)
	auth.from = mail.Address{mailname, mailacc}
	auth.in = make(chan *TksMailInfo)
	//
	go auth.run()
	return auth
}

func (t *TksMailAuth) run() {
	for {
		select {
		case info := <-t.in:
			t.sendMail(info.tomail, info.title, info.body)
		}
	}
}

func encodeRFC2047(String string) string {
	// use mail's rfc2047 to encode any string
	addr := mail.Address{String, ""}
	return strings.Trim(addr.String(), " <>")
}

func (t *TksMailAuth) sendMail(tomail string, title string, body string) error {
	to := mail.Address{"收件人", tomail}

	header := make(map[string]string)
	header["From"] = t.from.String()
	header["To"] = to.String()
	header["Subject"] = encodeRFC2047(title)
	header["MIME-Version"] = "1.0"
	header["Content-Type"] = "text/plain; charset=\"utf-8\""
	header["Content-Transfer-Encoding"] = "base64"

	message := ""
	for k, v := range header {
		message += fmt.Sprintf("%s: %s\r\n", k, v)
	}
	message += "\r\n" + base64.StdEncoding.EncodeToString([]byte(body))
	println(message)
	//
	return smtp.SendMail(
		t.server+":25",
		t.auth,
		t.from.Address,
		[]string{to.Address},
		[]byte(message),
	)
}

func (t *TksMailAuth) PutMail(info *TksMailInfo) {
	t.in <- info
}
